\label{protocol_spec}
\section{Introduction}

A network protocol is a set of rules which must be followed for a program to produce the desired effect on another machine in a network based system. The motivation behind creating a protocol is to allow a standard pattern of communication to be devised for a given system. This allows a system following the protocol to consistently perform the same role, in any context, regardless of its implementation. Any command in our protocol should produce a verifiable result as outlined in this section.

To guarantee any desired outcome, a `message' must be well formed (follow the correct syntax), be sent while the machine is in a valid `state,' and be sent within any expected time frame. This document outlines these aspects of our protocol in detail - specifying any constraint on when an action may be undertaken, and any constraint on the time allowed for this action to be performed. The outcome on the system state will also be detailed. Both aspects can be identified by the pre-conditions and post-conditions surrounding any given command.

In our framework, there is one machine that undertakes a `server' role, and many machines that can undertake a `client' role. These roles govern what a machine may validly send or receive, depending on its role. A general a pattern of communication, such that one role sending a `message' to the other results in a reply from this role, and a possible change of `state' in each member, will be evidenced in this section. To better understand our protocol, it is necessary to outline the function of these roles, with some reference to the states they maintain, to illuminate the utility of available messages.

At a high level, the role of the server is to keep a record of state persistent aspects of the user's account; composed of details such as login details, a buddy list, and privacy conditions. Further, it holds volatile state information, relevant only to a session (which can be defined as a state where the user is logged in). It monitors the global state of the system and relays information such as which buddies are available to message, and their state. Its pivotal role is to relay messages between clients. 

The role of the client is to allow the user to retrieve, via an interface, information regarding their buddies, and to send messages to the server which will subsequently be relayed to their buddies. Furthermore, it allows the user to modify their state within the system via the server.

\section{Commands}

\subsection{Command Structure}

Each message will follow this high level syntax: \\
\texttt{:COMMAND [ ARG1 \ \vline \ ARG2 \ \vline \ ARG3 ]: $<$data$>$;}

\begin{itemize}

\item{Square brackets [ ... ] denote a list of 1 or more arguments of which only one can be given and is required.}  

\item{Curly brackets \{ ... \} are used to represent arguments which are optional and can be non-singular.}

\item{A colon is used in the first instance to indicate the opening of a command, and in the second to indicate the boundary between a command's arguments and the data set.}

\item{Angular brackets $<$ … $>$ are used to show data that has been provided by the user and should be considered unsafe.}

\item{A semi colon ; is used to show the end of a command.}

\end{itemize}

By example:
\texttt{:GET \{ NICKNAME \ \vline \ STATUS \ \vline \ PERSONAL\_MESSAGE \ \vline \ DISPLAY\_PIC \}: $<$user$>$ $<$user$>$...;}\\
Could be used as follows: \\
\texttt{:GET NICKNAME STATUS PERSONAL\_MESSAGE: cyblob@idgmail.com meow@hotmail.com;} \\
Which means request the Nickname, Status and Personal Message of users cyblob@gmail.com and meow@hotmail.com.

Remarkably, this minimalistic structure is suitable to fulfill every requirement of the system and promote readability.

Every command or request which the sever receives must be followed by a response of some type. Where there is a command which does not return any data, the server should respond with the \texttt{:OKAY:} command to signal that the command was received and error free.

Commands have a maximum length of 8192 characters, including any punctuation, with the exception of the \texttt{:SET DISPLAY\_PIC:} command, which has a character limit of 32768.

\subsection{Heart Beat}

In order for the server to recognise that the client is still functioning, it must receive a command from the client on a regular basis (around every 15 seconds). In the event that no command is received for an extended period, the server will disconnect the client.

Any command will reset the timeout, however it is recommended that the \texttt{:PING:} command is used.

\section{Pre-login Commands}

These are the only commands possible before a user has logged in, and remain possible after the user has logged in.

These include all commands necessary for establishing a connection, logging into the server, and creating a new account.

\subsection{Server Commands}
\label{servercomm}

\texttt{:PING:;}

The command is used as a keep-alive command. Its primary use is to indicate that the client is still alive even if no other communication has been received from the client. 

Examples:
\texttt{:PING: ;} \\
The client responding to a \texttt{:PING:} command

{\bf :SERVERSTATUS \{ USERS \ \vline \ TIME \ \vline \ UPTIME \}:;}

The \texttt{:SERVERSTATUS:} command returns information about the server including the number of users, the local system time, and server up-time.
 
In the case that an argument is provided, the server should then return a \texttt{:SERVERSTATUS:} as defined in the client section. If more than one argument is provided, then the server should return each value on a new line in the order which the arguments were received (reading from left to right).

The arguments for this command are as follows:

\begin{itemize}

\item{ \texttt{USERS} \\
The total number of users and number of online users}

\item{ \texttt{TIME} \\
The current local time of the server}

\item{ \texttt{UPTIME} \\
The up-time of the server instance}

\end{itemize}

Examples:
\texttt{:SERVERSTATUS USERS:;} \\
Response$>$:\texttt{SERVERSTATUS USERS: 23 Online, 565 Total} \\
\texttt{:SERVERSTATUS TIME:;} \\
Response$>$:\texttt{SERVERSTATUS TIME: Wed 17 Nov, 23:31} \\

{\bf :AUTH \{ LOGIN \ \vline \ REGISTER \}: $<$email address$>$ $<$password$>$;}

The \texttt{:AUTH:} command deals with all aspects of user authorisation and permissions. The \texttt{:AUTH:} command alone should return the user's current authorisation state, either \texttt{LOGGEDIN} or \texttt{UNAUTHORIZED}.

{\bf LOGIN}

If the details are valid then the server should respond with an \texttt{:AUTH LOGGEDIN:} command. It should set the user's state (but not status) to \texttt{ONLINE}.
In the event that an error occurs the server should generate one of the following \texttt{:ERROR:} statuses:

\texttt{USER\_DOES\_NOT\_EXIST}\\
The email address has not been registered \\
\texttt{LOGIN\_DETAILS\_INCORRECT} \\
The password was incorrect \\
\texttt{MISSING\_ARGUMENTS} \\
There were too few arguments \\

If the user is already logged in then the server should send a \texttt{LOGGED\_IN\_FROM\_OTHER\_LOCATION} error and \texttt{KILL} command to the already connected user.

{\bf REGISTER}

The register argument allows for new users to be registered by providing a valid email address and password. If the new account is registered correctly then the server should respond with \texttt{:AUTH REGISTERED:}. However, it should not log the user in.

If the registration is unsuccessful the server should return one of the following \texttt{:ERROR:} messages:

\begin{itemize}

\item{\texttt{INVALID\_EMAIL} \\
The email address was invalid}

\item{\texttt{EMAIL\_ALREADY\_IN\_USE} \\
The email address has already been registered}

\item{\texttt{PASSWORD\_TOO\_SHORT} \\
The password is too short}

\item{\texttt{MISSING\_ARGUMENTS}	\\
There were too few arguments}

\end{itemize}

Examples:
\texttt{:AUTH REGISTER: cyblob@gmail.com p455w0rd;} \\
\texttt{:AUTH REGISTER: blah lol;} \\
Server responds \texttt{:ERROR INVALID\_EMAIL:} \\
\texttt{:AUTH LOGIN: cyblob@gmail.com p455w0rd;}\\
Server responds \texttt{:AUTH OKAY:} \\

{\bf :QUIT:;}

The \texttt{:QUIT:} command tells the server that the user wishes to log out (if applicable) and disconnect from the server. Once the quit command has been received, the user's state should be changed to \texttt{OFFLINE} and the connection broken.

Examples:
\texttt{:QUIT:;} \\
User is logged out and disconnected.

\subsection{Client Commands}

{\bf :OKAY:;}

In the event that a command received from the client does not have any other response, the \texttt{:OKAY:} command is sent to signify that the command was successful.

Examples:
\texttt{:OKAY:;}\\
The last command executed okay.

{\bf :SERVERSTATUS \{ USERS \ \vline \ TIME \ \vline \ UPTIME \}:;}

If requested by the client, the server may send data about the server status, as defined in section \ref{servercomm}. If more than one argument is provided then the data is returned with each segment on its own line, in the same order which the arguments appeared. If no arguments are provided then the data can be in any format containing any information. This command should not be assumed to have a consistent format.

Example:
\texttt{:SERVERSTATUS TIME: Wed 17 Nov, 23:31;} \\
\texttt{:SERVERSTATUS USERS: 56 Online, 423 Total;} \\
\texttt{:SERVERSTATUS UPTIME: 21 days, 14:41;} \\

{\bf :KILL: $<$message$>$;}

In the event that the server wants the client to disconnect, it will issue a \texttt{:KILL:} command. As soon as the command has been sent the server will disconnect. 

Example:
\texttt{:KILL: Too many bad login attempts.;}\\
The server closes the connection.

{\bf :BROADCAST: $<$message$>$;}

A \texttt{:BROADCAST:} message sent by the server to all users. The broadcast message should be displayed immediately and is likely to contain critical information about the server.

Example:
\texttt{:BROADCAST: The server is on fire and about to crash. ;}

{\bf :AUTH [ LOGGEDIN \ \vline \ UNAUTHORIZED ]:;}

The \texttt{:AUTH:} command indicates to the client its current status. If the user is logged in then it will have the \texttt{LOGGEDIN} argument, otherwise it will have the \texttt{UNAUTHORISED} argument.

Example:
\texttt{:AUTH LOGGEDIN:;}\\
The user is logged in and has permissions to use post-login commands

\section{Post-login Commands}

These commands are accessible only once the user has logged in. The server should issue an \texttt{:ERROR UNAUTHORISED:} response if an unauthorised user attempts to use one of these commands. After repeated attempts, the server may temporarily block or ban the user.

\subsection{Server Commands}

{\bf :SET [ NICKNAME\ \vline \ STATUS \ \vline \ PERSONAL\_MESSAGE \ \vline \ DISPLAY\_PIC ]: $<$value$>$;}

The \texttt{:SET:} command allows various user attributes to be set by the client. The exact attribute depends on the argument given however only one attribute can be set at a time. In the case of \texttt{DISPLAY\_PIC}, the image is Base64 encoded.

Example:
\texttt{:SET NICKNAME: Andrew;} \\

{\bf :GET \{ NICKNAME\ \vline \ STATUS \ \vline \ PERSONAL\_MESSAGE \ \vline \ DISPLAY\_PIC \}: $<$user$>$\{$<$user$>$\};} \\

The \texttt{:GET:} command requests a set of attributes for each user in a space separated list of users. The server should respond with an \texttt{:INFO:} command and the appropriate data.

Example:
\texttt{:GET NICKNAME STATUS PERSONAL\_MESSAGE DISPLAY\_PIC: user1@host.com, user2@hotmail.com;}

{\bf :FRIENDLIST:;}

The \texttt{:FRIENDLIST:} command requests a list of users in the user's friend list. It should return a \texttt{:FREINDLIST:} command as specified in section \ref{clientcomm_post}.

Example: \\
\texttt{:FREINDLIST:} 
	
{\bf :ROOM [ CREATE \{GROUP\} \ \vline \ INVITE \ \vline \ JOIN \ \vline \ LEAVE \ \vline \ USERS \ \vline \ TYPE ]: \{$<$roomid$>$ \ \vline \ $<$user$>$\};}

The \texttt{:ROOM:} command deals with all room related requests.

\begin{itemize}

\item{CREATE \\
The \texttt{CREATE} argument specifies that the client wishes to create a new chat room for use. If the \texttt{GROUP} argument is not supplied then the room will be limited to a maximum of two participants and a userID must be supplied so that the server can invite the other user. Upon creation of the room, the user who created it is automatically placed in the room.}

\item {INVITE \\
The \texttt{INVITE} argument sends an invite to join the room to the specified user. They are then allowed to join the room at any point.}

\item{JOIN \\
The \texttt{JOIN} argument specifies that the user wishes to join the specified room. The must first have received an invite from someone already in the room.}

\item{LEAVE \\
The \texttt{LEAVE} argument specifies that the user wishes to leave the specified room.}

\item{USERS \\
The \texttt{USERS} argument requests a list of users in the room from the server, separated by spaces.}

\end{itemize}

\texttt{:MESSAGE: $<$roomid$>$ $<$message$>$;}

The \texttt{:MESSAGE:} command specifies a room and a message which should be delivered to the room.

Example: \\
\texttt{:MESSAGE: 25 Hey guys, what's up?;}

{\bf :FRIEND [ ADD \ \vline \ BLOCK \ \vline \ UNBLOCK \ \vline \ ACCEPT \ \vline \ DECLINE \ \vline \ DELETE ]: $<$target$>$;}

The \texttt{:FRIEND:} command controls all friend list data.

\begin{itemize}

\item{ADD \\
The \texttt{ADD} argument specifies that the client wishes to add the target user to their friend list. The server should then send a request to the target user asking for permission to access their data.}

\item{BLOCK \\
The \texttt{BLOCK} argument places the target user into a list of blocked users who cannot access any data about the current user.}

\item{UNBLOCK \\
The \texttt{UNBLOCK} argument removes the target from the current user's blocked list.}

\item{ACCEPT \\
The \texttt{ACCEPT} argument specifies that the user is responding to a previous friend request, where the target is the user who sent the request. If the user accepts, then the target user should be given permission to use the user's data.}

\item{DELETE \\
The \texttt{DELETE} argument specifies that the target user should be deleted from the users friend list. However, the target user will still have access to the user's details.}

\item{DECLINE \\
The \texttt{DECLINE} argument specifies that the user does not wish the target user to be to able to access their data.}

\end{itemize}

Example: \\
\texttt{:FRIEND ADD: cyblob@gmail.com;}	\\
Request access to cyblob@gmail.com's data

{\bf :LOGOUT:;}

The \texttt{:LOGOUT:} command specifies that the client wishes to logout but not drop the connection to the server.

Example: \\
\texttt{:LOGOUT:;}\\
The user is logged out

\subsection{Client Commands}
\label{clientcomm_post}

{\bf :MESSAGE: $<$roomid$>$ $<$sender$>$ $<$message$>$;}

The \texttt{:MESSAGE:} command represents a message received by the user. The sender is the email address of the person who sent the message, and the message is the message itself.

Example: \\
\texttt{:MESSAGE: 56 cyblob@gmail.com How's it going?;}

{\bf :ROOM [ CREATED \ \vline \ JOINED \ \vline \ LEFT \ \vline \ INVITED \ \vline \ USERS \ \vline \ PERSONAL \ \vline \ GROUP ]: $<$roomid$>$ \{$<$user$>$\};}

\begin{itemize}

\item{CREATED \\
The \texttt{CREATED} argument tells the client that their request to create a room was successful and specifies the room id.}

\item{JOINED \\
The \texttt{JOINED} argument tells the client that a new user has joined the room and specifies the room and id of the user who joined.}

\item{LEFT \\
The \texttt{LEFT} argument tells the client that a user has left the room and specifies the room and the id of the user who left.}

\item{INVITED \\
The \texttt{INVITED} argument tells the client that they have been invited to join a room. It specifies the room and the user who invited them.}

\item{USERS \\
The \texttt{USERS} argument provides a list of users (one per line) who are currently in the room.}

\item{PERSONAL \\
The \texttt{PERSONAL} argument tells the client that the room is a personal room (no more than two users).}

\item{GROUP \\
The \texttt{GROUP} argument tells the client that the room is a group room and any number of users can join.}
	
\end{itemize}

Example: \\
\texttt{:ROOM CREATED: 0;} \\
\texttt{:ROOM JOINED: 0 CYBLOB@GMAIL.COM;} \\
\texttt{:ROOM LEFT: 0 CYBLOB@GMAIL.COM;} \\
\texttt{:ROOM INVITED: 0 HAPPY0@GMAIL.COM;} \\
\texttt{:ROOM USERS: CYBLOB@GMAIL.COM HAPPY0@HOTMAIL.COM \\SOMEONEELSE@GMAAIL.COM ANOTHER@HOTMAIL.COM;} \\

{\bf :FRIENDLIST: ONLINE $<$user$>$ $<$user$>$... OFFLINE $<$user$>$ $<$user$>$... BLOCKED $<$user$>$ $<$user$>$...;}

The \texttt{:FRIENDLIST:} command specifies the user's friend list using the format specified above.

Example: \\
\texttt{:FREINDLIST: ONLINE cyblob@gmail.com blah@ddfdf.com OFFLINE meow@hotmail.com woof@gmail.com sheep@yahoo.com BLOCKED wtf@wtf.com;}

{\bf :FRIENDREQUEST: $<$user$>$ $<$nickname$>$;}

The \texttt{:FRIENDREQUEST:} command tells the client that the user has a friend request and specifies who sent it and their nickname at the time of sending. The client should then respond with the appropriate \texttt{:FRIEND:} command.

Example: \\
\texttt{:FRIENDREQUEST: cyblob@gmail.com James;}

{\bf :UPDATE [ NICKNAME\ \vline \ STATUS \ \vline \ PERSONAL\_MESSAGE \ \vline \ DISPLAY\_PIC \ \vline \ FRIENEDLIST  ]: $<$user$>$;}

The \texttt{:UPDATE:} command notifies the client that a user in their friend list has just updated one of their attributes. The client can then retrieve the updated attribute if necessary.

Example: \\
\texttt{:UPDATE NICKNAME: cyblob@gmail.com;}

\texttt{:INFO \{ NICKNAME \ \vline \ STATUS \ \vline \ PERSONAL\_MESSAGE \ \vline \ DISPLAY\_PIC \}: $<$user$>$ $<$data$>$ \{$<$user$>$ $<$data$>$\};} 

The data is returned one line per value, in the same order as the arguments given, separated by the user's email address. In the case of \texttt{DISPLAY\_PIC}, the image is Base64 encoded to enable it to be embedded as text.

Example: \\

\texttt{:INFO NICKNAME STATUS PERSONAL\_MESSAGE DISPLAY\_PIC: user1@host.com \\
James \\
Away \\
I’m a panda \\
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBAQFBAYFBQYJBgUGCQsIBgYICwwKCgsK... \\
user2@host.com \\
Gordon \\
Online \\
I’m not a panda \\
DAREAAhEBAxEB/8QAHQAAAgIDAQEBAAAAAAAAAAAABAUDBgECBwAICf/EAE4QAAIBAg...;}

\texttt{:ERROR [ UNAUTHORISED \ \vline \ INVALID\_EMAIL \ \vline \ \\ EMAIL\_ALREADY\_IN\_USE \ \vline \ PASSWORD\_TOO\_SHORT \ \vline \ MISSING\_ARGUMENTS \ \vline \ \\ TOO\_MANY\_ARGUMENTS \ \vline \ INVALID\_ARGUMENT \ \vline \ LOGGED\_IN\_FROM\_OTHER\_LOCATION \ \vline \ \\ USER\_DOES\_NOT\_EXIST \ \vline \ LOGIN\_DETAILS\_INCORRECT ]: $<$message$>$;}

If an error occurs then the server should return one of these commands to the client. The exact command and the message will be specified by the sever.

Example: \\
\texttt{:ERROR INVALID\_EMAIL: No domain specified.;}
